package org.tradeinterceptor.modular.strategy.modules;

import java.util.logging.Logger;

import org.tradeinterceptor.modular.strategy.ForexSignal;
import org.tradeinterceptor.modular.strategy.StrategyModule;


import com.riflexo.charting.api.AbstractEasyCalculator;
import com.riflexo.charting.api.StockIndicator;
import com.riflexo.charting.api.StockIndicatorUtil;

public class MacdStrategyModule implements StrategyModule {

	private StockIndicator<Object> MACD;
	private int shortPeriod;
	private int longPeriod;
	private int signalPeriod;
	
	private double previousMacd = 0;
	private double previousMacdSignal = 0;
	
	private int closeCounter = 0;
	int maxCloseCounter = 0;
	
	boolean inPosition = false;
	ForexSignal positionDirection;
	
	Logger logger;
	
	public MacdStrategyModule(int longPeriod, int shortPeriod, int signalPeriod) {
		this.shortPeriod = shortPeriod;
		this.longPeriod = longPeriod;
		this.signalPeriod = signalPeriod;
	}
	
	@Override
	public ForexSignal getSignal() {
		
		ForexSignal signal = ForexSignal.STAND_ASIDE;
		
		if(!inPosition && (((getCurrentMacd() > getCurrentMacdSignal())&&(previousMacd < previousMacdSignal))
				||((getCurrentMacd() > getCurrentMacdSignal()) && ((getCurrentMacd() - getCurrentMacdSignal()) >= (previousMacd - previousMacdSignal))))){
			signal = ForexSignal.BUY;
		}else if(!inPosition && (((getCurrentMacd() < getCurrentMacdSignal())&&(previousMacd > previousMacdSignal))
				||((getCurrentMacd() < getCurrentMacdSignal()) && ((getCurrentMacdSignal() - getCurrentMacd()) >= (previousMacdSignal - previousMacd))))){
			signal = ForexSignal.SELL;
		} else if(inPosition){
			// Check the close criteria
			if((positionDirection == ForexSignal.BUY) && (previousMacd > getCurrentMacd())){
				if(closeCounter == maxCloseCounter){
					signal = ForexSignal.CLOSE;
				} else {
					closeCounter++;
				}
			}else if((positionDirection == ForexSignal.SELL) && (previousMacd < getCurrentMacd())){
				if(closeCounter == maxCloseCounter){
					signal = ForexSignal.CLOSE;
				} else {
					closeCounter++;
				}
			}
		}
		
		
		previousMacd = getCurrentMacd();
		previousMacdSignal = getCurrentMacdSignal();
		
		
		return signal;
	}
	
	@Override
	public void setPosition(ForexSignal signal) {
		inPosition = true;
		positionDirection = signal;
	}
	
	@Override
	public void close() {
		// TODO Auto-generated method stub
		inPosition = false;
		closeCounter = 0;
	}
	
	private double getCurrentMacd(){
		return MACD.get(StockIndicatorUtil.MACDChannels.MACD
				.toString());
	}
	
	private double getCurrentMacdSignal(){
		return MACD.get(StockIndicatorUtil.MACDChannels.SIGNAL
				.toString());
	}
	
	@Override
	public void declare(AbstractEasyCalculator parent) {
		MACD = parent.getStockIndicatorUtil().declareMACD("macd",
				shortPeriod, longPeriod,
				signalPeriod);
		
		logger = parent.getLogger();
	}
	
}
